// Programers: Burton Copeland and Jon Stewart
  // Purpose: to create a video game that will be able to use all the parts of programing classes and to try to expand what we are able to do


import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class textrpg extends JFrame
{
private static String password = "hiddenness";
public static String name;  // character name
public static int lstr, lspeed, lhealth, lave, wpn, dmg, health, packspace, money;  // levels, stats, inventory stuff, money
public static ArrayList<String> Inventory = new ArrayList<String>(0);
public static boolean[] done=new boolean[10];
public static boolean loaded=false;
/*
0 - home chest
1 - backpack
2 - map */

public static String[] Help=new String[10];

//construct menu
public textrpg()
{
     //sets up menu items
    JMenu Menu = new JMenu("Menu");
    JMenuItem NewGame = new JMenuItem("New Game");
    Menu.add(NewGame);
    JMenuItem Continue=new JMenuItem("Continue");
    Menu.add(Continue);
    JMenu LoadGame = new JMenu("Load Game");
    JMenuItem load1 = new JMenuItem("Slot 1");
    JMenuItem load2 = new JMenuItem("Slot 2");
    JMenuItem load3 = new JMenuItem("Slot 3");
    LoadGame.add(load1);
    LoadGame.add(load2);
    LoadGame.add(load3);
    Menu.add(LoadGame);    
    JMenu Options = new JMenu("Options");
    JMenuItem Hacks = new JMenuItem("debug");
    Options.add(Hacks);
    Menu.add(Options);
    JMenuItem Quit = new JMenuItem("Quit");
    Menu.add(Quit);
     
    //adding action listener to menu items
    NewGame.addActionListener(
       new ActionListener(){
           public void actionPerformed(ActionEvent e)
           {
               dispose();
               Beginning();
           }
       }
    );
        Continue.addActionListener(
           new ActionListener(){
               public void actionPerformed(ActionEvent e)
               {
                   dispose();
                   if (loaded==true){
                   JOptionPane.showMessageDialog(null, "Stats\nYour strength is: "+lstr+"\nYour speed is: "+lspeed+
          "\nYour health is: "+health+" \nyou are level: "+lave+"\nyou have "+money+" Moneys \nTo look at your stats just type ''stats'Â’ into the action bar.\nTo check available options type ''help''");
                   library.a();}
                   else{
                       JOptionPane.showMessageDialog(null, "Nothing has been loaded!");
                   startmenu();
                   }
               }
           }
       );
    load1.addActionListener(
       new ActionListener(){
           public void actionPerformed(ActionEvent e)
           {
               dispose();
               Load("save1");
           }
       }
    );
    load2.addActionListener(
           new ActionListener(){
               public void actionPerformed(ActionEvent e)
               {
                   dispose();
                   Load("save2");
               }
           }
       );
    load3.addActionListener(
           new ActionListener(){
               public void actionPerformed(ActionEvent e)
               {
                   dispose();
                   Load("save3");
               }
           }
       );
    Hacks.addActionListener(
           new ActionListener(){
               public void actionPerformed(ActionEvent e)
               {
                   dispose();
                   JOptionPane.showMessageDialog(null,"Debug to be...");
               }
           }
       );    
    Quit.addActionListener(
           new ActionListener(){
               public void actionPerformed(ActionEvent e)
               {
        //quits application
                   System.exit(0);
               }
           }
       );    
    //adds bar for menu to be on
    JMenuBar bar = new JMenuBar();
    setJMenuBar(bar);
    bar.add(Menu);
     
    getContentPane();
    setSize(200, 200);
    setVisible(true);
}


//main
public static void main(String[] args){
         startmenu();

}
//startmenu
public static void startmenu(){
//bring up menu
    textrpg app = new textrpg();
    app.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
//beginning
public static void Beginning(){
//clear inventory
   textrpg.Inventory.add("nothing");
    lstr=0;
    lspeed=0;
    lhealth=0;
    lave = (lstr+lspeed+lhealth)/3;
    health = (lhealth+1)*5;
    wpn = 0;
    dmg=lstr*5+wpn;
    Arrays.fill(done, false);
    packspace=4;
    money=10;
    name = JOptionPane.showInputDialog("Hello, this is the world of Attollit, \nbecause in video games I apparently have to specify \nthe frickinÂ’ world youÂ’re in because you are \nobviosly suffering from amnesia.  \n I take it you are new here. What is your name?","What do you call yourself?");
     
    JOptionPane.showMessageDialog(null, "Welcome to our world "+name+" since this is an RPG adventure you have stats.\nYour strength is: "+lstr+"\nYour speed is: "+lspeed+
          "\nYour health is: "+health+" \nyou are level: "+lave+"\nyou have "+money+" Moneys \nTo look at your stats just type ''stats'Â’ into the action bar.\nTo check available options type ''help''");
    library.a();
}
//save
public static void Saving() throws IOException{
    String[] buttons = { "slot 1","slot 2","slot 3","cancel"};
    int location = JOptionPane.showOptionDialog(null, "Which Slot?", "", JOptionPane.PLAIN_MESSAGE, -1, null, buttons, buttons[0]);
    String filename="";
    switch (location){
      case 0 : filename="save1";
      break;
      case 1 : filename="save2";
      break;
      case 2 : filename="save3";
      break;
      default : return;
    }
    try {
        int saving=JOptionPane.YES_OPTION;
       File file = new File(filename+".txt");
       File filesav = new File(filename+".sav");
       if (filesav.exists()) {
    	   saving = JOptionPane.showConfirmDialog(null, "There is already a file there. \nWould you like to overwrite?");
       }
       if (saving==JOptionPane.YES_OPTION){
    //sets up printing to textfile
       file.createNewFile();
       ObjectOutputStream bw=new ObjectOutputStream(new FileOutputStream(file));
       bw.writeObject(lstr);
       bw.writeObject(lspeed);
       bw.writeObject(lhealth);
       bw.writeObject(wpn);
       bw.writeObject(done);
       bw.writeObject(packspace);   
       bw.writeObject(money);     
       bw.writeObject(name);
       bw.writeObject(Inventory);
       bw.close();
       de_encrypt(false, filename);
       JOptionPane.showMessageDialog(null, "Save Complete");
       }
    } catch (IOException e) {
       e.printStackTrace();
    }
    catch (Exception fail){
    	fail.printStackTrace();
    }
}
//load
    public static void Load(String filename){
       try {
           File filesav = new File(filename+".sav");
           if (!filesav.exists())
               JOptionPane.showMessageDialog(null, "There is no data.");
           else {
           File file = new File(de_encrypt(true, filename));
    //sets up data reader
           ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
           lstr=(Integer) in.readObject();
           lspeed=(Integer) in.readObject();
           lhealth=(Integer) in.readObject();
           wpn=(Integer) in.readObject();
               done=(boolean[]) in.readObject();
           packspace=(Integer)in.readObject();
           money=(Integer) in.readObject();
           name= (String) in.readObject();
          Inventory = (ArrayList<String>) in.readObject();
           lave = (lstr+lspeed+lhealth)/3;
           health = (lhealth+1)*5;
           in.close();
           file.delete();}
       }
    catch (IOException e) {e.printStackTrace();
    }
    catch (Exception fail){
    	fail.printStackTrace();
    	JOptionPane.showMessageDialog(null, "No save found");
    }
loaded=true;
startmenu();
}
    public static String de_encrypt(boolean de, String filename) throws Exception
    {
            FileInputStream inFile;
            FileOutputStream outFile;
            if (de==false){
       inFile = new FileInputStream(filename+".txt");
       outFile = new FileOutputStream(filename+".sav");
            }
            else{
             inFile = new FileInputStream(filename+".sav");
                 outFile = new FileOutputStream(filename+".txt");
            }

       PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
       SecretKeyFactory keyFactory =
           SecretKeyFactory.getInstance("PBEWithMD5AndDES");
       SecretKey passwordKey = keyFactory.generateSecret(keySpec);


       byte[] salt = new byte[8];
       if (de==false){
       Random rnd = new Random();
       rnd.nextBytes(salt);}
       else
           inFile.read(salt);
       int iterations = 100;

       PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterations);

       Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
       if (de==false){
       cipher.init(Cipher.ENCRYPT_MODE, passwordKey, parameterSpec);
       outFile.write(salt);
       }
       else
       cipher.init(Cipher.DECRYPT_MODE, passwordKey, parameterSpec);


       
       byte[] input = new byte[64];
       int bytesRead;
       while ((bytesRead = inFile.read(input)) != -1)
       {
          byte[] output = cipher.update(input, 0, bytesRead);
          if (output != null) outFile.write(output);
       }

       byte[] output = cipher.doFinal();
       if (output != null) outFile.write(output);

       inFile.close();
       outFile.flush();
       outFile.close();
       return (filename+".txt");
   }

}

     
     



